package com.zgw.fireline.design.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.LineStyleEvent;
import org.eclipse.swt.custom.LineStyleListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.wb.swt.SWTResourceManager;

/**
 * 关键字高亮编辑器。This class is a simple customized widget that wrappes a  {@link org.eclipse.swt.custom.StyledText StyledText}. 
 * It consumes a keyword array and highlight them.
 * @author ggfan@amarsoft
 *
 */
public class KeywordsHighlightingEditor extends Composite{
    
    private Color color = SWTResourceManager.getColor(SWT.COLOR_BLUE);
    
    private Color variableColor = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);

    private String[] keywords;
    
    private StyledText st;
    
    public void setKeywordsColor(Color color){
        this.color = color;
    }
    
    public void setKeywordsBgColor(Color color){
    
    }
    
    public IObservableValue observerContent(){
        return SWTObservables.observeText(st, SWT.Modify);
    }

    public KeywordsHighlightingEditor(Composite parent, String[] keywords) {
        super(parent, SWT.NONE);
        this.keywords = keywords;
        this.setLayout(new FillLayout());
        st = new StyledText(this, SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
        // 禁止回车键换行
        st.addVerifyKeyListener(new VerifyKeyListener(){
            public void verifyKey(VerifyEvent event) {
                if(event.keyCode == SWT.CR){
                    event.doit = false;
                }
            }
        });
        // Tab键失去焦点而不是插入制表符
        st.addTraverseListener(new TraverseListener(){
            public void keyTraversed(TraverseEvent e) {
                if (e.detail == SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
                    e.doit = true;
                }
            }
        });
        st.addLineStyleListener(new SQLSegmentLineStyleListener());
    }
    
    private class SQLSegmentLineStyleListener implements LineStyleListener {

        public void lineGetStyle(LineStyleEvent event) {
            if(keywords == null || keywords.length == 0){
                return;
            }
            List<StyleRange> styles = new ArrayList<StyleRange>();
            int start = 0;
            int length = event.lineText.length();
            while (start < length) {
                if (Character.isLetter(event.lineText.charAt(start))) {
                    StringBuffer buf = new StringBuffer();
                    int i = start;
                    for (; i < length && Character.isLetter(event.lineText.charAt(i)); i++) {
                        buf.append(event.lineText.charAt(i));
                    }
                    if(Arrays.asList(keywords).contains(buf.toString())) {
                        styles.add(new StyleRange(event.lineOffset + start, i - start, color, null, SWT.BOLD));
                    }
                    start = i;
                }else if (event.lineText.charAt(start) == '#') {
                    StringBuffer buf = new StringBuffer();
                    buf.append('#');
                    int i = start + 1;
                    for (; i < length && Character.isLetter(event.lineText.charAt(i)); i++) {
                        buf.append(event.lineText.charAt(i));
                    }
                    if(buf.toString().matches("#[a-zA-Z]+\\d?")) {
                        styles.add(new StyleRange(event.lineOffset + start, i - start, variableColor, null, SWT.NORMAL));
                    }
                    start = i;
                }
                else{
                    start ++;
                }
            }
            event.styles = (StyleRange[]) styles.toArray(new StyleRange[0]);
        }

    }
    
}
